package com.rs.game.player.content;

import java.io.Serializable;

import com.rs.game.npc.*;
import com.rs.game.player.Player;
import com.rs.game.player.Skills;
import com.rs.utils.Utils;

/**
 * @author Wolfey
 * @author Mystic Flow
 * @author Bandoswhips
 */
public class SlayerTask implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3885979679549716755L;

	public enum Master {
		SPRIA(8273, new Object[][] { 
				{ "Crawling hand", 5, 15, 50, 16.0, 1 },
				{ "Bat", 1, 15, 50, 8.0, 1 },
				{ "Cow", 1, 15, 50, 8.0, 1 },
				{ "Goblin", 1, 15, 50, 5.0, 1 },
				{ "Spider", 1, 15, 50, 5.0, 1 }
		}),
		ACHTRYN(8274, new Object[][] {
				{ "Bat", 1, 40, 85, 8.0, 1 },
				{ "Cockatrice", 25, 40, 85, 37.0, 20 },
				{ "Hill Giant", 1, 40, 70, 35, 1 },
				{ "Skeleton", 1, 40, 70, 17, 1 }
		}),
		VANNAKA(1597, new Object[][] {
				{ "Aberrant spectre", 60, 60, 120, 90.0, 1 },
				{ "Bloodveld", 50, 60, 120, 120.0, 1 },
				{ "Infernal mage", 45, 60, 120, 60.0, 1 },
				{ "Jelly", 52, 60, 120, 75.0, 1 },
				{ "Cockatrice", 25, 60, 120, 37.0, 1 },
				{ "Green dragon", 1, 30, 60, 75.0, 1 },
				{ "Lesser demon", 1, 60, 120, 79.0, 1 }
		}),
		CHAELDAR(1598, new Object[][] {
				{ "Aberrant spectre", 60, 110, 170, 90.0, 1 },
				{ "Bloodveld", 50, 110, 170, 120.0, 1 },
				{ "Blue dragon", 1, 110, 170, 107.6, 1 },
				{ "Cave horror", 58, 110, 170, 55.0, 1 },
				{ "Crawling hand", 5, 110, 170, 16.0, 1 },
				{ "Gargoyle", 75, 110, 170, 105.0, 1 },
				{ "Jelly", 52, 110, 170, 75.0, 1 },
				{ "Lesser demon", 1, 110, 170, 79.0, 1 },
				{ "Jungle strykewyrm", 73, 90, 110, 110.0, 1 }
		}),
		SUMONA(7780, new Object[][] {
				{ "Aberrant spectre", 60, 120, 185, 90.0, 1 },
				{ "Abyssal demon", 85, 120, 185, 150.0, 1 },
				{ "Bloodveld", 50, 120, 185, 120.0, 1 },
				{ "Blue dragon", 1, 120, 185, 107.6, 1 },
				{ "Cave horror", 58, 120, 185, 55.0, 1 },
				{ "Gargoyle", 75, 120, 185, 105.0, 1 },
				{ "Greater demon", 1, 120, 185, 87.0, 1 },
				{ "Hellhound", 1, 120, 185, 116.0, 1 },
				{ "Iron dragon", 1, 30, 85, 173.2, 1 },
				{ "Nechryael", 80, 120, 185, 105.0, 1 },
				{ "Red Dragon", 1, 30, 79, 50.0, 1 },
				{ "Spiritual Mage", 83, 120, 185, 71.0, 1 },
				{ "Desert strykewyrm", 77, 90, 120, 120.0, 1 },
				{ "Jungle strykewyrm", 73, 90, 120, 110.0, 1 }
		}),
		LAPALOK(8275, new Object[][] {
				{ "Aberrant spectre", 60, 130, 200, 90.0, 1 },
				{ "Abyssal demon", 85, 130, 200, 150.0, 1 },
				{ "Bloodveld", 50, 130, 200, 120.0, 1 },
				{ "Dark beast", 90, 130, 200, 225.0, 1 },
				{ "Gargoyle", 75, 130, 200, 105.0, 1 },
				{ "Greater demon", 1, 130, 200, 87.0, 1 },
				{ "Hellhound", 1, 130, 200, 116.0, 1 },
				{ "Iron dragon", 1, 40, 80, 173.2, 1 },
				{ "Nechryael", 80, 130, 200, 105.0, 1 },
				{ "Steel dragon", 1, 40, 80, 220.4, 1 },
				{ "Spiritual Mage", 83, 120, 185, 71.0, 1 },
				{ "Ice strykewyrm", 93, 100, 200, 300.0, 1 },
				{ "Desert strykewyrm", 77, 90, 140, 120.0, 1 },
				{ "Jungle strykewyrm", 73, 90, 140, 110.0, 1 }
		}),
		KURADAL(9085, new Object[][] { 
				{ "Aberrant spectre", 60, 140, 250, 90.0, 1 },
				{ "Abyssal demon", 85, 150, 250, 150.0, 1 },
				{ "Blue dragon", 1, 120, 200, 107.6, 1 },
				{ "Dark beast", 90, 150, 250, 225.0, 1 },
				{ "Greater demon", 1, 150, 250, 87.0, 1 },
				{ "Hellhound", 1, 130, 230, 116.0, 1 },
				{ "Iron dragon", 1, 40, 117, 173.2, 1 },
				{ "Steel dragon", 1, 40, 108, 220.4, 1 },
				{ "Gargoyle", 75, 150, 250, 105.0, 1 },
				{ "Ice strykewyrm", 93, 100, 219, 300.0, 1 },
				{ "Desert strykewyrm", 77, 90, 160, 120.0, 1 },
				{ "Grifolapine", 88, 130, 200, 235.0, 1 },
				{ "Grifolaroo", 82, 100, 200, 210, 1 },
				{ "Ganodermic beast", 95, 50, 150, 360.0, 1 },
				{ "Ganodermic Runt", 95, 50, 135, 353, 1 }, 
				{ "Fungal mage", 1, 79, 135, 67.0, 1 },
				{ "Fungal rodent", 1, 50, 135, 50.4, 1 },
				{ "Jungle strykewyrm", 73, 90, 160, 110.0, 1 }
		});

		private int id;
		private Object[][] data;

		private Master(int id, Object[][] data) {
			this.id = id;
			this.data = data;
		}

		public static Master forId(int id) {
			for (Master master : Master.values()) {
				if (master.id == id) {
					return master;
				}
			}
			return null;
		}

		public int getId() {
			return id;
		}

	}

	private Master master;
	private int taskId;
	private int taskAmount;
	private int amountKilled;

	public SlayerTask(Master master, int taskId, int taskAmount) {
		this.master = master;
		this.taskId = taskId;
		this.taskAmount = taskAmount;
	}

	public String getName() {
		return (String) master.data[taskId][0];
	}

	public static SlayerTask random(Player player, Master master) {
		SlayerTask task = null;
		while (true) {
			int random = Utils.random(master.data.length - 1);
			int requiredLevel = (Integer) master.data[random][1];
			int requiredDef = (Integer) master.data[random][5];
			if (player.getSkills().getLevelForXp(Skills.SLAYER) < requiredLevel) {
				continue;
			}
			if (player.getSkills().getLevelForXp(Skills.DEFENCE) < requiredDef) {
				continue;
			}
			int minimum = (Integer) master.data[random][2];
			int maximum = (Integer) master.data[random][3];
			if (task == null) {
				task = new SlayerTask(master, random, Utils.random((minimum / 2), (maximum / 2)));
				player.setTask(task);
			}
			break;
		}
		return task;
	}

	public int getTaskId() {
		return taskId;
	}
	
	/**
	 * Get the task amount
	 * 
	 * @return
	 */
	public int getTaskAmount() {
		return taskAmount;
	}
	
	/**
	 * Decrease the task amount
	 * 
	 */
	public void decreaseAmount() {
		taskAmount--;
	}

	public int getXPAmount() {
		Object obj = master.data[taskId][4];
		if (obj instanceof Double) {
			return (int) Math.round((Double) obj);
		}
		if (obj instanceof Integer) {
			return (Integer) obj;
		}
		return 0;
	}

	public Master getMaster() {
		return master;
	}

	/**
	 * @return the amountKilled
	 */
	public int getAmountKilled() {
		return amountKilled;
	}

	/**
	 * @param amountKilled
	 *            the amountKilled to set
	 */
	public void setAmountKilled(int amountKilled) {
		this.amountKilled = amountKilled;
	}

	public void onMonsterDeath(Player player, NPC n) {
		player.getSkills().addXp(Skills.SLAYER, player.getTask().getXPAmount());
		player.getTask().decreaseAmount();
		player.getTask().setAmountKilled(player.getTask().getAmountKilled() + 1);
		player.getPackets().sendGameMessage("You need to defeat " + player.getTask().getTaskAmount() + " " + player.getTask().getName().toLowerCase() + " to complete your task.");
		if (player.getTask().getTaskAmount() < 1) {
			player.setTask(null);
			player.taskCount++;
			if (player.taskCount % 50 == 0) {
				player.setSlayerPoints(player.getSlayerPoints() + 270);
				player.getPackets().sendGameMessage("You've completed " + player.taskCount + " tasks in a row and gain 270 points.");
			} else if (player.taskCount % 10 == 0) {
				player.setSlayerPoints(player.getSlayerPoints() + 90);
				player.getPackets().sendGameMessage("You've completed " + player.taskCount + " tasks in a row and gain 90 points.");
			} else if (player.taskCount >= 3) {
				player.setSlayerPoints(player.getSlayerPoints() + 18);
				player.getPackets().sendGameMessage("You've completed " + player.taskCount + " tasks in a row and gain 18 points.");
			} else {
				player.getPackets().sendGameMessage("You will gain slayer points after completing at least 3 tasks.");
			}
		}
	}
}
